package com.grm.security.details;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.grm.common.Result;
import com.grm.sys.entity.SysUser;
import com.grm.sys.service.SysUserService;
import com.grm.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * 用户验证处理
 *
 * @author gaorimao
 * @date 2022/02/07
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private HttpServletResponse response;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 根据用户名查用户
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        SysUser user = sysUserService.getOne(wrapper);
        if (ObjectUtils.isEmpty(user)) {
            Result.renderJsonStr(response, Result.failed(500, "登录用户：" + username + "不存在"));
        }
        return createLoginUser(user);
    }

    /**
     * 创建登录用户
     *
     * @param sysUser 系统用户
     * @return {@link UserDetails}
     */
    private UserDetails createLoginUser(SysUser sysUser) {
        LoginUser loginUser = new LoginUser();
        // 设置用户id，用户名，密码，用户图标
        loginUser.setUserId(sysUser.getId());
        loginUser.setUsername(sysUser.getUsername());
        loginUser.setPassword(sysUser.getPassword());
        loginUser.setAvatar(sysUser.getAvatar());
        // 已授予的权限
        String authority = sysUserService.getUserAuthorityInfo(sysUser.getId());
        List<GrantedAuthority> grantedAuthorities = AuthorityUtils.commaSeparatedStringToAuthorityList(authority);
        loginUser.setAuthorities(grantedAuthorities);

        /*
         大坑--------解决匿名用户的问题
            --------security每次请求离开时，会在SecurityContextPersistenceFilter中清除SecurityContextHolder;
            --------所以我们通过redis把loginUser缓存起来,设置7天有效期，和token保持一致
            --------自定义一个JwtAuthenticationTokenFilter,利用loginUser生成UsernamePasswordAuthenticationToken,
            --------重新set进SecurityContextHolder.getContext().setAuthentication()
         */
        redisUtil.set("LoginUser:" + sysUser.getUsername(), loginUser, 60 * 60 * 24 * 7);
        return loginUser;
    }
}

